package com.sgy.springmvc_demo.controller;

import com.sgy.springmvc_demo.pojo.User;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

@Controller
@RequestMapping("/demo")
public class DemoController {

    // springmvc异常处理机制
    /*@ExceptionHandler(value = ArithmeticException.class)
    public void handleException(ArithmeticException exception, HttpServletResponse response) {
        try {
            response.getWriter().write(exception.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }*/

    @RequestMapping("/handle01")
    public ModelAndView handle01(@ModelAttribute("name") String name) {
        Date date = new Date();
        ModelAndView modelAndView = new ModelAndView();
        // addObject相当于向请求域中request.setAttribute("date", date)
        modelAndView.addObject("date", date);
        modelAndView.setViewName("success");
        return modelAndView;
    }


    /*
    * springmvc在handler方法上传入Map、ModelMap、Model参数，并向这些参数中保存数据，都可以在页面上获取到
    * 它们运行时，具体类型都是BindingAwareModelMap
    * BindingAwareModelMap extends ExtendedModelMap
    * ExtendedModelMap extends ModelMap implements Model
    * ModelMap extends LinkedHashMap<String, Object>
    * LinkedHashMap<K,V> extends HashMap<K,V> implements SequencedMap<K,V>
    * HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>
    * */

    @RequestMapping("/handle11")
    public String handle11(ModelMap modelMap) {
        Date date = new Date();
        modelMap.addAttribute("date", date);
        return "success";
    }

    @RequestMapping("/handle12")
    public String handle12(Model model) {
        Date date = new Date();
        model.addAttribute("date", date);
        return "success";
    }

    @RequestMapping("/handle13")
    public String handle13(Map<String, Object> map) {
        Date date = new Date();
        map.put("date", date);
        return "success";
    }

    @RequestMapping("/handle14")
    public String handle14(@RequestParam Date birthday) {
        Date date = new Date();
        return "success";
    }

    /*
    * @RequestBody：接收json格式传参
    * @ResponseBody：不再走视图解析器，而是等同于response直接输出数据
    * */
    @RequestMapping("/handle15")
    @ResponseBody
    public User handle15(@RequestBody User user) {
        user.setName("张三");
        return user;
    }

    @RequestMapping("/handle16")
    public ModelAndView handle16(@RequestPart MultipartFile file, HttpSession httpSession) throws IOException {

        // 原始名称
        String originalFilename = file.getOriginalFilename();
        String ext = originalFilename.substring(originalFilename.lastIndexOf(".") + 1, originalFilename.length());
        String newName = UUID.randomUUID().toString() + "." + ext;

        // 存储到指定文件夹
        String realPath = httpSession.getServletContext().getRealPath("/uploads");
        String datePath = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        File file1 = new File(realPath + "/" + datePath);
        if (!file1.exists()) {
            file1.mkdirs();
        }

        // 存储文件到目录
        file.transferTo(new File(file1, newName));

        Date date = new Date();
        ModelAndView modelAndView = new ModelAndView();
        // addObject相当于向请求域中request.setAttribute("date", date)
        modelAndView.addObject("date", date);
        modelAndView.setViewName("success");
        return modelAndView;
    }

    /*
    * 重定向传参
    * */
    @RequestMapping("/handle17")
    public String handle17(@RequestParam String name, RedirectAttributes redirectAttributes) {
        // addFlashAttribute相当于设置了一个flush类型属性，该属性会被暂存到session中，在跳转到页面之后会被销毁
        redirectAttributes.addFlashAttribute("name", name);
        return "redirect:handle01";
    }
}
